package model

import (
	"context"
	"log"

	"go.mongodb.org/mongo-driver/bson"
)

type UserRoom struct {
	UserIdentity string `bson:"user_identity"`
	RoomIdentity string `bson:"room_identity"`
	RoomType     int    `bson:"room_type"`
	CreatedAt    int64  `bson:"created_at"`
	UpdatedAt    int64  `bson:"updated_at"`
}

func (UserRoom) CollectionName() string {
	return "user_room"
}

func GetUserRoomByUserIdentityRoomIdentity(userIdentity, roomIdentity string) (*UserRoom, error) {
	ur := new(UserRoom)
	err := InitMongo().Collection(UserRoom{}.CollectionName()).
		FindOne(context.Background(),
			bson.D{
				{"user_identity", userIdentity},
				{"room_identity", roomIdentity},
			}).Decode(ur)
	return ur, err
}

func DeleteUserRoom(roomIdentity string) error {
	_, err := InitMongo().Collection(UserRoom{}.CollectionName()).
		DeleteOne(context.Background(), bson.M{"room_identity": roomIdentity})
	if err != nil {
		log.Println("delete user room failed: ", err)
		return err
	}
	return nil
}

func InsertOneUserRoom(ur *UserRoom) error {
	_, err := Mongo.Collection(UserRoom{}.CollectionName()).
		InsertOne(context.Background(), ur)
	return err
}

func GetUserRoomIdentity(userIdentity1, userIdentity2 string) string {
	cursor, err := Mongo.Collection(UserRoom{}.CollectionName()).
		Find(context.Background(),
			bson.D{
				{"user_identity", userIdentity1},
				{"room_type", 1},
			})
	roomIdentities := make([]string, 0)
	if err != nil {
		log.Println("failed to get user room: ", err)
		return ""
	}

	for cursor.Next(context.Background()) {
		ur := new(UserRoom)
		err := cursor.Decode(ur)
		if err != nil {
			log.Println("failed to decode user room: ", err)
			return ""
		}
		roomIdentities = append(roomIdentities, ur.RoomIdentity)
	}

	ur := new(UserRoom)
	err = Mongo.Collection(UserRoom{}.CollectionName()).
		FindOne(context.Background(),
			bson.M{"user_identity": userIdentity2,
				"room_type": 1,
				"room_identity": bson.M{
					"$in": roomIdentities,
				},
			},
		).Decode(ur)
	if err != nil {
		log.Println("failed to get user room: ", err)
		return ""
	}

	return ur.RoomIdentity
}

func GetUserRoomByRoomIdentity(roomIdentity string) ([]*UserRoom, error) {
	cursor, err := Mongo.Collection(UserRoom{}.CollectionName()).
		Find(context.Background(), bson.D{{
			"room_identity", roomIdentity,
		}})
	if err != nil {
		return nil, err
	}
	urs := make([]*UserRoom, 0)
	for cursor.Next(context.Background()) {
		ur := new(UserRoom)
		err := cursor.Decode(ur)
		if err != nil {
			return nil, err
		}
		urs = append(urs, ur)
	}

	return urs, nil

}
